package com.example.supernote.ui.note.components

import android.Manifest
import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContract
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CameraAlt
import androidx.compose.material.icons.filled.EmergencyRecording
import androidx.compose.material.icons.filled.KeyboardVoice
import androidx.compose.material.icons.filled.Upload
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.example.supernote.R
import com.example.supernote.ui.components.UniformButton
import com.example.supernote.ui.components.UniformDialog
import com.example.supernote.ui.components.UniformPreviewBody
import com.example.supernote.ui.components.UniformToast
import com.example.supernote.ui.utils.getPermissionLauncher
import com.example.supernote.ui.utils.getShowInfos
import java.io.File

@Composable
fun ShowGetorDialog(
    onCancel: () -> Unit,
    onConfirm: (sourceUri: Uri, sourceName: String) -> Unit,
    contractUpload: ActivityResultContract<Unit?, Uri?>,
    contractCamera: ActivityResultContract<Unit?, Uri?>?,
    dialogTitle: String
) {
    var sourceUri: Uri? by remember { mutableStateOf(null) }
    var sourceName: String by remember { mutableStateOf("") }
    val context = LocalContext.current
    val warn = stringResource(R.string.note_text_warning)
    val showInfos = getShowInfos(dialogTitle)
    val method = showInfos["method"]!!
    var uploadPreview by remember { mutableStateOf(false) }
    var cameraPreview by remember { mutableStateOf(false) }
    var showAudioRecorder by remember { mutableStateOf(false) }
    var showGetorDialog by remember { mutableStateOf(true) }

    val cameraFunction: (Uri) -> Unit = {
        sourceUri = it
        sourceName = ""
        cameraPreview = true
        uploadPreview = false
    }

    if (showAudioRecorder) {
        AudioRecorder(
            getFilePath = {
                it?.let { cameraFunction(Uri.fromFile(File(it))) }
            },
            onCancel = { showAudioRecorder = false; showGetorDialog = true }
        )
    } else {
        UniformDialog(
            title = dialogTitle,
            onCancel = onCancel,
            onConfirm = {
                sourceUri?.let { onConfirm(it, sourceName) } ?: run { UniformToast(context, warn) }
            },
            body = {
                val uploadLauncher =
                    rememberLauncherForActivityResult(contract = contractUpload) {
                        it?.let {
                            sourceUri = it
                            sourceName = ""
                            cameraPreview = false
                            uploadPreview = true
                        }
                        showGetorDialog = true
                    }
                val cameraLauncher = contractCamera?.let {
                    rememberLauncherForActivityResult(contract = contractCamera) {
                        it?.let { cameraFunction(it) }
                        showGetorDialog = true
                    }
                }
                val uploadPermission =
                    getPermissionLauncher({ uploadLauncher.launch(null); showGetorDialog = false })
                val cameraPermission =
                    if (method == "audio") getPermissionLauncher({ showAudioRecorder = true })
                    else getPermissionLauncher({ cameraLauncher!!.launch(null); showGetorDialog = false })

                if (showGetorDialog && (uploadPreview || cameraPreview)) {
                    UniformPreviewBody(
                        title = stringResource(R.string.note_preview_select),
                        sourceUri = sourceUri,
                        method = method
                    )
                    TextField(
                        value = sourceName,
                        onValueChange = { sourceName = it },
                        placeholder = {
                            Text(
                                text = showInfos["tip"]!!,
                                style = MaterialTheme.typography.bodySmall,
                                color = MaterialTheme.colorScheme.onBackground
                            )
                        })
                }

                Row {
                    UniformButton(
                        modifier = Modifier.weight(1f),
                        onClick = { uploadPermission.launch(Manifest.permission.READ_EXTERNAL_STORAGE) },
                        imageVector = Icons.Filled.Upload,
                        text = if (uploadPreview) stringResource(R.string.note_upload_after) else stringResource(
                            R.string.note_upload_before
                        )
                    )
                    Spacer(modifier = Modifier.width(5.dp))
                    UniformButton(
                        modifier = Modifier.weight(1f),
                        onClick = {
                            if (method == "audio") cameraPermission.launch(Manifest.permission.RECORD_AUDIO)
                            else cameraPermission.launch(Manifest.permission.CAMERA)
                        },
                        imageVector = getImageVector(method),
                        text = if (cameraPreview) showInfos["takeMediaAfter"] else showInfos["takeMediaBefore"]
                    )
                }
            }
        )
    }
}

fun getImageVector(method: String): ImageVector =
    when (method) {
        "image" -> Icons.Filled.CameraAlt
        "audio" -> Icons.Filled.KeyboardVoice
        else -> Icons.Filled.EmergencyRecording
    }